#include "include/EventLoop.h"
#include "include/ILogger.h"
#include "include/TcpServer.h"
#include "include/TcpClient.h"
#include <iostream>
#include <queue>
#include <algorithm> 
#include <stdexcept>

#ifdef _WIN32
#define NOMINMAX
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mswsock.h>
#pragma comment(lib, "ws2_32.lib")
#define EPOLLIN 0x001
#define EPOLLOUT 0x004
#define EPOLLERR 0x008
#else
#include <sys/epoll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#endif

namespace Tool
{

EventType& operator++(EventType& type)
{
    type = static_cast<EventType>(static_cast<uint8_t>(type) + 1);
    return type;
}

EventType operator+(EventType type, int n)
{
    EventType temp = type;
    temp = static_cast<EventType>(static_cast<uint8_t>(temp) + n);
    return temp;
}

// 全局事件ID生成器
static std::atomic<int64_t> s_nextEventId{1};

// Event类实现
Event::Event(EventType t, EventPriority p, Variant d)
    : type(t)
    , priority(p)
    , data(std::move(d))
    , eventId(s_nextEventId.fetch_add(1))
    , userData(nullptr)
    , isOneShot(false)
    , timestamp(DataTime::Now())
{
}

MessageEvent::MessageEvent(int64_t id)
    : Event(EventType::Message)
    , msg_id(id)
{

}

MessageEvent::MessageEvent(int64_t id, const std::string& cnt, EventPriority p)
    : Event(EventType::Message, p)
    , msg_id(id)
    , content(cnt)
{
}

IOEvent::IOEvent(int fd, uint32_t ev, EventPriority p)
    : Event(EventType::IO, p)
    , socketFd(fd)
    , events(ev)
{
}

TimerEvent::TimerEvent(int64_t id, uint64_t interval, EventPriority p)
    : Event(EventType::Timer, p)
    , timerId(id)
    , intervalMs(interval)
{
}

void PriorityEventQueue::Push(std::shared_ptr<Event> event)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (!m_stopped && event)
    {
        m_queue.push(std::move(event));
        m_cv.notify_all();
    }
}
bool PriorityEventQueue::TryPop(std::shared_ptr<Event>& out, std::chrono::milliseconds timeout)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    if (m_cv.wait_for(lock, timeout, [this] { return m_stopped || !m_queue.empty(); }))
    {
        if (m_stopped)
        {
            return false;
        }
        out = std::move(m_queue.top());
        m_queue.pop();
        return true;
    }
    return false;
}
void PriorityEventQueue::Stop()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_stopped = true;
    m_cv.notify_all();
}

bool PriorityEventQueue::IsEmpty() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_queue.empty();
}

EventHandler::HandlerId EventHandler::RegisterHandler(EventType type, EventHandlerFunc func)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    EventHandler::HandlerId id = m_nextHandlerId++;
    m_handlers[type].emplace_back(id, std::move(func));
    return id;
}

bool EventHandler::RemoveHandler(EventType type, EventHandler::HandlerId id)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    auto it = m_handlers.find(type);
    if (it == m_handlers.end())
    {
        return false;
    }
    auto& handlers = it->second;
    auto eraseIt = std::remove_if(handlers.begin(), handlers.end(), 
        [id](const std::pair<EventHandler::HandlerId, EventHandlerFunc>& pair)
        {
            return pair.first == id;
        });
    if (eraseIt != handlers.end())
    {
        handlers.erase(eraseIt, handlers.end());
        return true;
    }
    return false;
}

void EventHandler::HandleEvent(std::shared_ptr<Event> event)
{
    if (!event)
    {
        return;
    }
    // std::lock_guard<std::mutex> lock(m_mutex);
    auto it = m_handlers.find(event->type);
    if (it != m_handlers.end())
    {
        for (const auto& [id, func] : it->second)
        {
            try
            {
                func(event);
            }
            catch (const std::exception& e)
            {
                LOG_ERROR("Event handle exception (handler %llu): %s", id, e.what());
            }
        }
    }
    else
    {
        LOG_ERROR("No handler for event type: %d", static_cast<int>(event->type));
    }
}


// HighResTimer类实现
HighResTimer::HighResTimer()
{
}

HighResTimer::~HighResTimer()
{
}

uint64_t HighResTimer::GetCurrentTimeMs() const
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();
}

int64_t HighResTimer::AddTimer(uint64_t intervalMs, std::function<void(int64_t)> callback, void* userData, bool isOneShot)
{
    if (intervalMs == 0 || !callback)
    {
        LOG_WARN("Invalid timer parameters: interval=%llu, callback=%s",
                 intervalMs, callback ? "valid" : "invalid");
        return -1;
    }

    int64_t timerId = m_nextTimerId.fetch_add(1);
    Timer timer;
    timer.id = timerId;
    timer.intervalMs = intervalMs;
    timer.nextRunTime = GetCurrentTimeMs() + intervalMs;
    timer.callback = std::move(callback);
    timer.userData = userData;
    timer.isOneShot = isOneShot;

    std::lock_guard<std::mutex> lock(m_mutex);
    auto [it, inserted] = m_timers.insert(timer);
    if (!inserted)
    {
        LOG_ERROR("Failed to add timer with id %lld", timerId);
        return -1;
    }

    LOG_DEBUG("Added timer: id=%lld, interval=%llums, oneshot=%s",
              timerId, intervalMs, isOneShot ? "true" : "false");
    return timerId;
}

bool HighResTimer::RemoveTimer(int64_t timerId)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    auto it = std::find_if(m_timers.begin(), m_timers.end(),
        [timerId](const Timer& timer)
        {
            return timer.id == timerId;
        });

    if (it != m_timers.end())
    {
        m_timers.erase(it);
        LOG_DEBUG("Removed timer: id=%lld", timerId);
        return true;
    }

    LOG_WARN("Timer not found for removal: id=%lld", timerId);
    return false;
}

void HighResTimer::Update()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    uint64_t currentTime = GetCurrentTimeMs();

    auto it = m_timers.begin();
    while (it != m_timers.end() && it->nextRunTime <= currentTime)
    {
        // 拷贝定时器对象，因为我们即将从集合中删除它
        Timer timer = *it;
        it = m_timers.erase(it);

        LOG_DEBUG("Executing timer callback: id=%lld", timer.id);
        try
        {
            timer.callback(timer.id);
        }
        catch (const std::exception& e)
        {
            LOG_ERROR("Timer callback exception (id=%lld): %s", timer.id, e.what());
        }

        // 如果不是一次性定时器，重新计算下次运行时间并添加回集合
        if (!timer.isOneShot)
        {
            timer.nextRunTime = currentTime + timer.intervalMs;
            m_timers.insert(timer);
            LOG_DEBUG("Rescheduled periodic timer: id=%lld, next run at %llu",
                      timer.id, timer.nextRunTime);
        }
    }
}

uint64_t HighResTimer::GetNextExpirationTime()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_timers.empty())
    {
        return UINT64_MAX; // 表示没有定时器
    }
    return m_timers.begin()->nextRunTime;
}

// IO多路复用器实现
#ifdef _WIN32
// Windows下扩展OVERLAPPED结构，关联socket和事件信息
struct IOCPOverlapped : public OVERLAPPED
{
    int socketFd;
    uint32_t events; // 记录关注的事件（EPOLLIN/EPOLLOUT等）
    
    IOCPOverlapped(int fd, uint32_t ev)
        : socketFd(fd)
        , events(ev)
    {
        Internal = 0;
        InternalHigh = 0;
        Offset = 0;
        OffsetHigh = 0;
        hEvent = nullptr;
    }
};

class IOCPMultiplexer : public IOMultiplexer
{
public:
    IOCPMultiplexer() 
        : m_iocp(INVALID_HANDLE_VALUE)
    {
    }

    ~IOCPMultiplexer() override
    {
        if (m_iocp != INVALID_HANDLE_VALUE)
        {
            CloseHandle(m_iocp);
            m_iocp = INVALID_HANDLE_VALUE;
        }
    }

    bool Initialize() override
    {
        m_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
        if (m_iocp == INVALID_HANDLE_VALUE)
        {
            LOG_ERROR("Failed to create IOCP: %d", GetLastError());
            return false;
        }
        LOG_DEBUG("IOCPMultiplexer initialized successfully");
        return true;
    }

    bool AddFd(int fd, uint32_t events) override
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        
        // 检查是否已存在
        if (m_overlaps.find(fd) != m_overlaps.end())
        {
            LOG_WARN("FD %d already exists in IOCPMultiplexer", fd);
            return false;
        }

        // 创建扩展的OVERLAPPED
        auto overlap = std::make_unique<IOCPOverlapped>(fd, events);
        
        // 将socket与IOCP绑定
        HANDLE handle = CreateIoCompletionPort(reinterpret_cast<HANDLE>(fd), m_iocp, 0, 0);
        if (!handle)
        {
            LOG_ERROR("CreateIoCompletionPort failed for FD %d: %d", fd, GetLastError());
            return false;
        }

        m_overlaps[fd] = std::move(overlap);
        LOG_DEBUG("Added FD %d to IOCPMultiplexer with events 0x%x", fd, events);
        return true;
    }

    bool RemoveFd(int fd) override
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        auto it = m_overlaps.find(fd);
        if (it == m_overlaps.end())
        {
            LOG_WARN("FD %d not found in IOCPMultiplexer", fd);
            return false;
        }

        m_overlaps.erase(it);
        LOG_DEBUG("Removed FD %d from IOCPMultiplexer", fd);
        return true;
    }

    bool ModifyFd(int fd, uint32_t events) override
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        auto it = m_overlaps.find(fd);
        if (it == m_overlaps.end())
        {
            LOG_WARN("FD %d not found in IOCPMultiplexer for modification", fd);
            return false;
        }

        it->second->events = events;
        LOG_DEBUG("Modified FD %d in IOCPMultiplexer with new events 0x%x", fd, events);
        return true;
    }

    int Wait(std::vector<std::pair<int, uint32_t>>& activeEvents, int timeoutMs) override
    {
        DWORD bytesTransferred;
        ULONG_PTR key;
        OVERLAPPED* overlapped;

        BOOL result = GetQueuedCompletionStatus(
            m_iocp,
            &bytesTransferred,
            &key,
            &overlapped,
            timeoutMs == -1 ? INFINITE : timeoutMs
        );

        if (!result)
        {
            DWORD err = GetLastError();
            if (err != WAIT_TIMEOUT)
            {
                LOG_ERROR("GetQueuedCompletionStatus failed: %d", err);
            }
            return 0;
        }

        if (overlapped)
        {
            IOCPOverlapped* ioOverlap = static_cast<IOCPOverlapped*>(overlapped);
            activeEvents.emplace_back(ioOverlap->socketFd, ioOverlap->events);
            LOG_DEBUG("IO event detected for FD %d, events 0x%x", ioOverlap->socketFd, ioOverlap->events);
            return 1;
        }

        return 0;
    }

private:
    HANDLE m_iocp;
    std::unordered_map<int, std::unique_ptr<IOCPOverlapped>> m_overlaps;
    std::mutex m_mutex;
};
#else
class EpollMultiplexer : public IOMultiplexer
{
public:
    EpollMultiplexer() 
        : m_epollFd(-1)
    {
    }

    ~EpollMultiplexer() override
    {
        if (m_epollFd != -1)
        {
            close(m_epollFd);
            m_epollFd = -1;
        }
    }

    bool Initialize() override
    {
        m_epollFd = epoll_create1(0);
        if (m_epollFd == -1)
        {
            LOG_ERROR("epoll_create1 failed: %d", errno);
            return false;
        }
        LOG_DEBUG("EpollMultiplexer initialized successfully");
        return true;
    }

    bool AddFd(int fd, uint32_t events) override
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;
        
        if (epoll_ctl(m_epollFd, EPOLL_CTL_ADD, fd, &ev) == -1)
        {
            LOG_ERROR("epoll_ctl add failed for FD %d: %d", fd, errno);
            return false;
        }
        
        LOG_DEBUG("Added FD %d to EpollMultiplexer with events 0x%x", fd, events);
        return true;
    }

    bool RemoveFd(int fd) override
    {
        if (epoll_ctl(m_epollFd, EPOLL_CTL_DEL, fd, nullptr) == -1)
        {
            LOG_ERROR("epoll_ctl remove failed for FD %d: %d", fd, errno);
            return false;
        }
        
        LOG_DEBUG("Removed FD %d from EpollMultiplexer", fd);
        return true;
    }

    bool ModifyFd(int fd, uint32_t events) override
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;
        
        if (epoll_ctl(m_epollFd, EPOLL_CTL_MOD, fd, &ev) == -1)
        {
            LOG_ERROR("epoll_ctl modify failed for FD %d: %d", fd, errno);
            return false;
        }
        
        LOG_DEBUG("Modified FD %d in EpollMultiplexer with new events 0x%x", fd, events);
        return true;
    }

    int Wait(std::vector<std::pair<int, uint32_t>>& activeEvents, int timeoutMs) override
    {
        struct epoll_event events[1024];
        int numEvents = epoll_wait(m_epollFd, events, 1024, timeoutMs);

        if (numEvents < 0)
        {
            if (errno != EINTR)
            {
                LOG_ERROR("epoll_wait error: %d", errno);
            }
            return 0;
        }

        activeEvents.reserve(numEvents);
        for (int i = 0; i < numEvents; ++i)
        {
            int fd = events[i].data.fd;
            uint32_t event = events[i].events;
            activeEvents.emplace_back(fd, event);
        }

        // LOG_DEBUG("Epoll wait returned %d active events", numEvents);
        return numEvents;
    }

private:
    int m_epollFd;
};
#endif

// EventLoop类实现
EventLoop::EventLoop(int threadPoolSize)
    : m_queue(std::make_unique<PriorityEventQueue>())
    , m_handler(std::make_shared<EventHandler>())
    , m_threadPool(std::make_unique<ThreadPool>(threadPoolSize))
    , m_timer(std::make_unique<HighResTimer>())
{
#ifdef _WIN32
    m_ioMultiplexer = std::make_unique<IOCPMultiplexer>();
#else
    m_ioMultiplexer = std::make_unique<EpollMultiplexer>();
#endif

    if (!m_ioMultiplexer->Initialize())
    {
        LOG_ERROR("Failed to initialize IO multiplexer!");
        throw std::runtime_error("IO multiplexer initialization failed");
    }
    
    LOG_DEBUG("EventLoop created with thread pool size: %d", threadPoolSize);
}

EventLoop::~EventLoop()
{
    Stop();
    LOG_DEBUG("EventLoop destroyed");
}

void EventLoop::Start()
{
    if (m_running)
    {
        LOG_WARN("EventLoop is already running!");
        return;
    }

    m_running = true;
    m_thread = std::thread(&EventLoop::Loop, this);
    LOG_INFO("EventLoop started in new thread");
}

void EventLoop::Stop()
{
    if (m_running == false)
    {
        return;
    }

    m_running = false;
    m_queue->Stop();
    m_threadPool->Stop();
    
    if (m_thread.joinable())
    {
        m_thread.join();
    }
    
    LOG_INFO("EventLoop stopped");
}

void EventLoop::Run()
{
    if (m_running)
    {
        LOG_WARN("EventLoop is already running!");
        return;
    }
    
    m_running = true;
    Loop();  // 在当前线程运行事件循环
}

void EventLoop::PostEvent(std::shared_ptr<Event> event)
{
    if (event && m_running)
    {
        m_queue->Push(event);
        // LOG_DEBUG("Event posted: id=%lld, type=%d, priority=%d",
        //           event->eventId, static_cast<int>(event->type), static_cast<int>(event->priority));
    }
    else if (!m_running)
    {
        LOG_WARN("Cannot post event to stopped EventLoop!");
    }
    else
    {
        LOG_WARN("Attempted to post null event!");
    }
}

EventHandler::HandlerId EventLoop::RegisterHandler(EventType type, EventHandlerFunc func)
{
    auto handlerId = m_handler->RegisterHandler(type, std::move(func));
    LOG_DEBUG("Registered handler %llu for event type %d", handlerId, static_cast<int>(type));
    return handlerId;
}

bool EventLoop::UnregisterHandler(EventType type, EventHandler::HandlerId handlerId)
{
    bool result = m_handler->RemoveHandler(type, handlerId);
    if (result)
    {
        LOG_DEBUG("Unregistered handler %llu for event type %d", handlerId, static_cast<int>(type));
    }
    else
    {
        LOG_WARN("Failed to unregister handler %llu for event type %d", handlerId, static_cast<int>(type));
    }
    return result;
}

bool EventLoop::AddIOEvent(int fd, uint32_t events)
{
    bool result = m_ioMultiplexer->AddFd(fd, events);
    if (result)
    {
        LOG_DEBUG("Added IO event for FD %d, events 0x%x", fd, events);
    }
    return result;
}

bool EventLoop::RemoveIOEvent(int fd)
{
    bool result = m_ioMultiplexer->RemoveFd(fd);
    if (result)
    {
        LOG_DEBUG("Removed IO event for FD %d", fd);
    }
    return result;
}

bool EventLoop::ModifyIOEvent(int fd, uint32_t events)
{
    bool result = m_ioMultiplexer->ModifyFd(fd, events);
    if (result)
    {
        LOG_DEBUG("Modified IO event for FD %d, new events 0x%x", fd, events);
    }
    return result;
}

int64_t EventLoop::AddTimer(uint64_t intervalMs, std::function<void(int64_t)> callback, void* userData, bool isOneShot)
{
    return m_timer->AddTimer(intervalMs, std::move(callback), userData, isOneShot);
}

bool EventLoop::RemoveTimer(int64_t timerId)
{
    return m_timer->RemoveTimer(timerId);
}

void EventLoop::Loop()
{
    LOG_INFO("EventLoop started in thread: %zu", std::hash<std::thread::id>{}(std::this_thread::get_id()));

    while (m_running)
    {
        // 处理定时器事件
        m_timer->Update();

        // 计算IO多路复用的超时时间（基于下一个定时器的到期时间）
        uint64_t nextTimerTime = GetNextTimerTime();
        uint64_t now = m_timer->GetCurrentTimeMs();
        int timeoutMs = (nextTimerTime != UINT64_MAX) ? static_cast<int>(nextTimerTime - now) : 10;
        // 确保超时时间不为负，且至少1ms避免过度频繁唤醒
        timeoutMs = std::max(1, timeoutMs);

        // 处理IO事件
        std::vector<std::pair<int, uint32_t>> activeEvents;
        int numEvents = m_ioMultiplexer->Wait(activeEvents, timeoutMs);
        if (numEvents > 0)
        {
            for (const auto& [fd, events] : activeEvents)
            {
                auto ioEvent = std::make_shared<IOEvent>(fd, events);
                PostEvent(ioEvent);
            }
        }

        // 处理队列事件
        ProcessPendingEvents();
    }
    
    LOG_INFO("EventLoop stopped in thread: %zu", std::hash<std::thread::id>{}(std::this_thread::get_id()));
}

void EventLoop::ProcessPendingEvents()
{
    std::shared_ptr<Event> event;
    int timeout = 1; // 1ms超时，避免阻塞
    bool result = m_queue->TryPop(event, std::chrono::milliseconds(timeout));
    
    while (result && m_running)
    {
        // LOG_DEBUG("Processing event: id=%lld, type=%d", event->eventId, static_cast<int>(event->type));
        // 提交到线程池处理事件，避免阻塞事件循环
        auto handler = m_handler;
        m_threadPool->PostTask([event, handler]() mutable
        {
            handler->HandleEvent(event);
        });
            
        result = m_queue->TryPop(event, std::chrono::milliseconds(timeout));
    }
}

uint64_t EventLoop::GetNextTimerTime() const
{
    return m_timer->GetNextExpirationTime();
}

}  // namespace Tool
